package com.yungu.swift.api.route.v1.driver;

import com.alibaba.dubbo.config.annotation.Reference;
import com.github.miemiedev.mybatis.paginator.domain.PageList;
import com.yungu.swift.api.base.BaseApi;
import com.yungu.swift.assets.driver.model.dto.DriverDto;
import com.yungu.swift.assets.driver.model.dto.DriverQueueDto;
import com.yungu.swift.assets.driver.model.vo.QueueSiteVO;
import com.yungu.swift.assets.driver.service.DriverQueueService;
import com.yungu.swift.assets.driver.service.DriverService;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.base.model.annotation.ResponseImgOverride;
import com.yungu.swift.constants.CommonConstant;
import com.yungu.swift.constants.OrderConstant;
import com.yungu.swift.lbs.model.Coordinate;
import com.yungu.swift.lbs.service.DistanceService;
import com.yungu.swift.lbs.service.LocationService;
import com.yungu.swift.order.model.dto.OrderDto;
import com.yungu.swift.order.model.param.ApiJoinListParam;
import com.yungu.swift.order.model.vo.JsonOrderDetailVo;
import com.yungu.swift.order.service.OrderJoinService;
import com.yungu.swift.order.service.OrderService;
import com.yungu.swift.system.sys.model.dto.SysPointSiteDto;
import com.yungu.swift.assets.driver.model.vo.QueueCityVO;
import com.yungu.swift.system.sys.service.SysPointSiteService;
import com.yungu.swift.system.sys.service.SysWayService;
import com.yungu.swift.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 司机端拼车订单接口
 */
@Controller
@RequestMapping(value = "/api/v1/driver", method = {RequestMethod.POST, RequestMethod.GET})
@Api(value = "【司机】【订单】【跨城拼车】相关接口【亿的】", tags = "地址&参数调整[2017-12-20 14:28]")
public class DriJoinOrderApi extends BaseApi {

    @Reference
    private DriverQueueService driverQueueService;
    @Reference
    private SysWayService sysWayService;
    @Reference
    private DriverService driverService;
    @Reference
    private SysPointSiteService sysPointSiteService;
    @Reference
    private OrderService orderService;
    @Reference
    private OrderJoinService orderJoinService;
    @Reference
    private LocationService locationService;

    @Reference
    private DistanceService distanceService;

    @RequestMapping(value = {"/token/join/queue/up"})
    @ResponseBody
    @ApiOperation(value = "上班（&自动排队）接口 —— 已生效", response = ResponseData.class, notes = "DATA：null（依据最外层成功&失败确认）")
    public ResponseData<Map<String, Object>> queueUp(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(name = "driLng", value = "司机当前经度", required = true) @RequestParam Double driLng,
            @ApiParam(name = "driLat", value = "司机当前纬度", required = true) @RequestParam Double driLat,
            @ApiParam(name = "cityUuid", value = "城市ID", required = true) @RequestParam(required = false) String cityUuid,
            @ApiParam(name = "siteUuid", value = "位置点ID", required = true) @RequestParam String siteUuid,
            @ApiParam(name = "uploadText", value = "长连接上传的报文：待补充", required = false) @RequestParam(required = false) String uploadText,
            HttpServletRequest request) {
        return driverQueueService.queueUp(appid, getUserUid(request), driLng, driLat, uploadText,cityUuid,siteUuid);
    }

    @ResponseBody
    @RequestMapping(value = {"/token/crosstown/queueCity"})
    @ApiOperation(value = "排队城市拉取", response = ResponseData.class)
    public ResponseData<List<QueueCityVO>> queueCity(HttpServletRequest request) {
        String driverUuid = getUserUid(request);
        return driverQueueService.queueCity(driverUuid);
    }

    @ResponseBody
    @RequestMapping(value = {"/token/crosstown/queueSite"})
    @ApiOperation(value = "排队位置拉取", response = ResponseData.class)
    public ResponseData<List<QueueSiteVO>> queueSite(HttpServletRequest request) {
        String driverUuid = getUserUid(request);
        return driverQueueService.queueSite(driverUuid);
    }

    @RequestMapping(value = {"/token/join/queue/status"})
    @ResponseBody
    @ApiOperation(value = "司机排队状态检测接口 —— 已生效", response = ResponseData.class, notes = "DATA：<br/>onQueue:0未排队 1已排队")
    public ResponseData<Map<String, Object>> queueStatus(HttpServletRequest request) {
        return driverQueueService.queueStatus(getUserUid(request));
    }

    @RequestMapping(value = {"/token/join/queue/sites"})
    @ResponseBody
    @ApiOperation(value = "获取司机排队城市列表接口（即司机所属公司运营线路。含未排队城市）—— 已生效", response = SysPointSiteDto.class,
            notes = "Tip:目前返回线路数据，uuid:起点UUID（异步查询对应排队数据列表时使用），name:起点名称"
    )
    public ResponseData queueSites(@ApiParam(name = "driLng", value = "司机当前经度", required = true) @RequestParam Double driLng,
                                   @ApiParam(name = "driLat", value = "司机当前纬度", required = true) @RequestParam Double driLat,
                                   HttpServletRequest request) {
        Map<String, Object> map = new HashMap(2);
        map.put("uuid", getUserUid(request));
        DriverDto driver = driverService.get(map).getData();
        if (driver == null) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取司机信息失败");
        }
        //获取运营起点
        map.clear();
        map.put("appid", driver.getAppid());
        map.put("agentUuid", driver.getAgentUuid());
        map.put("companyUuid", driver.getCompanyUuid());
        map.put("status", CommonConstant.STATUS_OPENED);
        map.put("state", CommonConstant.STATE_NORMAL);
        ResponseData originRS = sysPointSiteService.findOrigins(map);
        if (!originRS.isSuccess()) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取排队城市失败");
        }
        List<SysPointSiteDto> origins = (List<SysPointSiteDto>) originRS.getData();

        //匹配司机当前排队城市：有排队、则返回排队中距离最近的出发点城市；否则返回全部起点中距离最近的出发点
        List<SysPointSiteDto> temps = new ArrayList<>();

        map.clear();
        map.put("driUuid", getUserUid(request));
        ResponseData queueRS = driverQueueService.list(map);
        if (queueRS.isSuccess()) {
            List<DriverQueueDto> qs = ((List<DriverQueueDto>) queueRS.getData());
            for (DriverQueueDto q : qs) {
                for (SysPointSiteDto origin : origins) {
                    if (origin.getUuid().equals(q.getOriginSiteUuid())) {
                        temps.add(origin);
                    }
                }
            }
        }

        /**
         * 距离最小匹配
         */
        if (null == temps || temps.isEmpty()) {
            temps = origins;
        }
        String targetOriginUuid = null;
        // 距离计算
        Double distance = Double.MAX_VALUE;
        double temp;
        for (int i = 0; i < temps.size(); i++) {
            ResponseData distanceRS = distanceService.getDistance(driLng, driLat, temps.get(i).getCenterLng(), temps.get(i).getCenterLat());
            if (distanceRS.isSuccess()) {
                temp = ((Double) distanceRS.getData());
                if (temp <= distance) {
                    distance = temp;
                    targetOriginUuid = temps.get(i).getUuid();
                }
            }
        }

        //赋值默认点
        if (StringUtils.isNotEmpty(targetOriginUuid)) {
            for (SysPointSiteDto origin : origins) {
                if (targetOriginUuid.equals(origin.getUuid())) {
                    origin.setMatchCurPoint(1);
                } else {
                    origin.setMatchCurPoint(0);
                }
            }
        }

        return ResponseData.buildSuccessResponse("获取排队城市成功", null == origins ? new ArrayList<>() : origins);
    }

    @RequestMapping(value = {"/token/join/queue/list"})
    @ResponseBody
    @ApiOperation(value = "排队列表接口 —— 已生效", response = DriverQueueDto.class)
    public ResponseData<List<DriverQueueDto>> listQueue(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(name = "originSiteUuid", value = "起点区域UUID", required = true) @RequestParam String originSiteUuid,
            HttpServletRequest request) {
        return driverQueueService.listQueue(getUserUid(request), originSiteUuid);
    }

    @RequestMapping(value = {"/token/join/queue/down"})
    @ResponseBody
    @ApiOperation(value = "收车（&主动停止排队）接口 —— 已生效", response = ResponseData.class, notes = "DATA：null（依据最外层成功&失败确认）")
    public ResponseData<DriverDto> queueDown(
            @RequestParam(required = false) Double offWorkLat,
            @RequestParam(required = false) Double offWorkLng,
            HttpServletRequest request) {
        Coordinate coordinate = new Coordinate();
        coordinate.setLng(offWorkLng);
        coordinate.setLat(offWorkLat);
        return driverQueueService.quit(getUserUid(request), coordinate);
    }

    @RequestMapping(value = {"/token/join/order/start"})
    @ResponseBody
    @ApiOperation(value = "开始行程接口 —— 已生效", response = JsonOrderDetailVo.class,
            notes = "DATA：订单详情（跨城拼车订单状态主要以joinStatus为准）"
                    + "<br>joinStatus：100提交（待支付）、200预约中（已支付）、300预约成功（待安排）、400已安排（待出发）、500行程开始、600行程结束（已完成）"
                    + "<br>typeJoin-拼车类型：1拼车 2包车"
                    + "<br>typeSelf-代叫类型：1本人 2代叫"
                    + "<br>wayUuid：线路UUID"
                    + "<br>payStatus-支付状态：0未支付 1已支付 2退款中 3已退款"
                    + "<br>closeStatus-关闭状态：0正常 1关闭"
                    + "<br>closeType-关闭类型：PAS_CANCEL乘客主动取消 DRI_CANCEL司机端取消【预留】 TIME_OUT超时系统自动取消 ADMIN_CLOSE后台关闭 默认：null"
                    + "<br>resNum-订单剩余人数，只有拼车主订单才会有数据"
    )
    public ResponseData<JsonOrderDetailVo> startOrder(
            @ApiParam(name = "orderUuid", value = "订单号", required = true) @RequestParam String orderUuid) {
        return orderJoinService.startJoinOrder(orderUuid);
    }

    @RequestMapping(value = {"/token/join/order/complete"})
    @ResponseBody
    @ApiOperation(value = "完成接口 —— 已生效\", response = JsonOrderDetailVo.class,\n" +
            "            notes = \"DATA：订单详情订单（跨城拼车订单状态主要以joinStatus为准）"
            + "<br>joinStatus：100提交（待支付）、200预约中（已支付）、300预约成功（待安排）、400已安排（待出发）、500行程开始、600行程结束（已完成）"
            + "<br>typeJoin-拼车类型：1拼车 2包车"
            + "<br>typeSelf-代叫类型：1本人 2代叫"
            + "<br>wayUuid：线路UUID"
            + "<br>payStatus-支付状态：0未支付 1已支付 2退款中 3已退款"
            + "<br>closeStatus-关闭状态：0正常 1关闭"
            + "<br>closeType-关闭类型：PAS_CANCEL乘客主动取消 DRI_CANCEL司机端取消【预留】 TIME_OUT超时系统自动取消 ADMIN_CLOSE后台关闭 默认：null"
            + "<br>resNum-订单剩余人数，只有拼车主订单才会有数据"
    )
    public ResponseData<JsonOrderDetailVo> completeOrder(
            @ApiParam(name = "orderUuid", value = "订单号", required = true) @RequestParam String orderUuid) {
        return orderJoinService.completeJoinOrder(orderUuid);
    }


    @RequestMapping(value = {"/token/join/order/list"})
    @ResponseBody
    @ApiOperation(value = "司机订单列表接口（具体返回数据可能比这个少）—— 已生效", response = OrderDto.class,
            notes = "DATA：订单详情（跨城拼车订单状态主要以joinStatus为准）"
                    + "<br>joinStatus：100提交（待支付）、200预约中（已支付）、300预约成功（待安排）、400已安排（待出发）、500行程开始、600行程结束（已完成）"
                    + "<br>typeJoin-拼车类型：1拼车 2包车"
                    + "<br>typeSelf-代叫类型：1本人 2代叫"
                    + "<br>wayUuid：线路UUID"
                    + "<br>payStatus-支付状态：0未支付 1已支付 2退款中 3已退款"
                    + "<br>closeStatus-关闭状态：0正常 1关闭"
                    + "<br>closeType-关闭类型：PAS_CANCEL乘客主动取消 DRI_CANCEL司机端取消【预留】 TIME_OUT超时系统自动取消 ADMIN_CLOSE后台关闭 默认：null"
                    + "<br>resNum-订单剩余人数，只有拼车主订单才会有数据"
    )
    public ResponseData<PageList<JsonOrderDetailVo>> listOrder(HttpServletRequest request) {
        ApiJoinListParam joinListParam = new ApiJoinListParam();
        joinListParam.setDriUuid(getUserUid(request));
        joinListParam.setStatusType("ALL");
        return orderJoinService.joinPageList(joinListParam);
    }


    @ResponseBody
    @RequestMapping(value = {"/token/join/order/info"})
    @ResponseImgOverride
    @ApiOperation(value = "订单详情接口 —— 已生效", response = JsonOrderDetailVo.class,
            notes = "DATA：订单详情（跨城拼车订单状态主要以joinStatus为准）"
                    + "<br>joinStatus：100提交（待支付）、200预约中（已支付）、300预约成功（待安排）、400已安排（待出发）、500行程开始、600行程结束（已完成）"
                    + "<br>typeJoin-拼车类型：1拼车 2包车"
                    + "<br>typeSelf-代叫类型：1本人 2代叫"
                    + "<br>wayUuid：线路UUID"
                    + "<br>payStatus-支付状态：0未支付 1已支付 2退款中 3已退款"
                    + "<br>closeStatus-关闭状态：0正常 1关闭"
                    + "<br>closeType-关闭类型：PAS_CANCEL乘客主动取消 DRI_CANCEL司机端取消【预留】 TIME_OUT超时系统自动取消 ADMIN_CLOSE后台关闭 默认：null"
                    + "<br>resNum-订单剩余人数，只有拼车主订单才会有数据"
    )
    public ResponseData<JsonOrderDetailVo> infoOrder(
            @ApiParam(name = "orderUuid", value = "订单id", required = true) @RequestParam String orderUuid,
            HttpServletRequest request) {
        if (StringUtils.isEmpty(orderUuid)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "参数错误");
        }
        return orderService.getOrderDetail(orderUuid, getUserUid(request));
    }


    @RequestMapping(value = {"/token/join/home/order"})
    @ResponseBody
    @ApiOperation(value = "首页订单接口 —— 已生效", response = ResponseData.class,
            notes = "DATA：订单详情（跨城拼车订单状态主要以joinStatus为准）"
                    + "<br>joinStatus：100提交（待支付）、200预约中（已支付）、300预约成功（待安排）、400已安排（待出发）、500行程开始、600行程结束（已完成）"
                    + "<br>typeJoin-拼车类型：1拼车 2包车"
                    + "<br>typeSelf-代叫类型：1本人 2代叫"
                    + "<br>wayUuid：线路UUID"
                    + "<br>payStatus-支付状态：0未支付 1已支付 2退款中 3已退款"
                    + "<br>closeStatus-关闭状态：0正常 1关闭"
                    + "<br>closeType-关闭类型：PAS_CANCEL乘客主动取消 DRI_CANCEL司机端取消【预留】 TIME_OUT超时系统自动取消 ADMIN_CLOSE后台关闭 默认：null"
                    + "<br>resNum-订单剩余人数，只有拼车主订单才会有数据"
    )
    public ResponseData<PageList<JsonOrderDetailVo>> homeOrder(HttpServletRequest request) {
        ApiJoinListParam joinListParam = new ApiJoinListParam();
        joinListParam.setDriUuid(getUserUid(request));
        joinListParam.setJoinStatus(Arrays.asList(OrderConstant.ORDER_JOIN_STATUS_WAIT_START, OrderConstant.ORDER_JOIN_STATUS_STARTED));
        joinListParam.setIndexShow(1);
        return orderJoinService.joinPageList(joinListParam);
    }

}
